package com.ybear.ybcomponent.base.adapter;

import android.view.View;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;

import com.ybear.ybcomponent.base.adapter.delegate.DelegateMultiSelect;
import com.ybear.ybcomponent.base.adapter.delegate.IDelegateMultiSelect;
import com.ybear.ybcomponent.base.adapter.listener.IMultiSelectListener;
import com.ybear.ybcomponent.base.adapter.listener.OnMultiSelectChangeListener;

import java.util.List;

/**
 * 多选版RecyclerView适配器
 * @param <E>
 */
public abstract class BaseMultiSelectAdapter<E extends IItemData, H extends BaseViewHolder> extends
        BaseRecyclerViewAdapter<E, H> implements
        IDelegateMultiSelect<E, H>, IMultiSelectListener<H> {

    private DelegateMultiSelect<E, H> mDelegate;

    public BaseMultiSelectAdapter(@NonNull List<E> mDataList) {
        super( mDataList );
        getDelegate().init( this );
        getDelegate().initAdapter( this );
    }

    /**
     * 获取多选委托
     * @return  委托
     */
    private DelegateMultiSelect<E, H> getDelegate() {
        return mDelegate == null ? mDelegate = DelegateMultiSelect.create() : mDelegate;
    }

    /**
     * 绑定ViewHolder
     * @param holder        Holder
     * @param position      当前Item的位置
     */
    @Override
    public void onBindViewHolder(@NonNull H holder, int position) {
        super.onBindViewHolder(holder, position);
        getDelegate().onBindViewHolder( holder, position );
    }

    /**
     * 绑定ViewHolder
     * @param holder        绑定的Holder
     * @param position      当前位置
     * @param isSelected    是否选中
     */
    @Override
    public abstract void onBindViewHolder(@NonNull H holder, int position, boolean isSelected);

    /**
     * 多选发生改变时
     * @param adapter       this
     * @param holder        Holder
     * @param position      选中的位置
     * @param isChecked     是否选中
     * @param fromUser      是否为用户发起
     */
    @Override
    public abstract void onMultiSelectChange(RecyclerView.Adapter<H> adapter, @Nullable H holder,
                                             int position, boolean isChecked, boolean fromUser);

    /**
     * 全选状态
     * @param adapter       适配器
     * @param isSelectAll   是否为全选状态
     * @param fromUser      是否为用户发起
     */
    @Override
    public void onMultiSelectAll(RecyclerView.Adapter<H> adapter, boolean isSelectAll,
                                 boolean fromUser) { }

    @Override
    public void onHolderChange(@NonNull H holder, int position, @HolderStatus int status) {
        getDelegate().onHolderChange( holder, position, status );
    }

    /**
     * Item被点击
     * @param adapter   this
     * @param v         点击的View
     * @param data      Item数据
     * @param position  位置
     */
    @Override
    public void onItemClick(RecyclerView.Adapter<H> adapter, View v, E data, int position) {
        super.onItemClick( adapter, v, data, position );
        getDelegate().onItemClick( position );
    }

    /**
     * 委托传入的View切换选中状态 - touch
     * 当View的Touch被抬起时触发
     * @param v             委托的View
     * @param position      选中的位置
     */
    @Override
    public void delegateMultiView(View v, int position) {
        getDelegate().delegateMultiView( v, position );
    }

    /**
     * 委托传入的View切换选中状态 - click
     * @param v             委托的View
     * @param position      选中的位置
     */
    @Override
    public void delegateMultiViewClick(View v, int position) {
        getDelegate().delegateMultiViewClick( v, position );
    }

    /**
     * 设置Item被点击时选项处理的方式
     * @param type  反选：      {@link ItemClickType#SWITCH}
     *              勾选：      {@link ItemClickType#ENABLE}
     *              取消勾选：   {@link ItemClickType#DISABLE}
     */
    @Override
    public void setItemClickType(@ItemClickType int type) {
        getDelegate().setItemClickType( type );
    }

    /**
     * 设置多选发生改变时事件监听器
     * @param l     监听器
     */
    @Override
    public void setOnMultiSelectChangeListener(OnMultiSelectChangeListener<H> l) {
        getDelegate().setOnMultiSelectChangeListener( l );
    }

    /**
     * 是否启用多选
     * @param enable    启用多选
     */
    @Override
    public void setEnableMultiSelect(boolean enable) {
        getDelegate().setEnableMultiSelect( enable );
    }

    /**
     * 是否启用多选并且初始化
     * @param enable    启用多选
     */
    @Override
    public void setEnableMultiSelectAndInit(boolean enable) {
        getDelegate().setEnableMultiSelectAndInit( enable );
    }

    /**
     * 设置自动勾选隐藏的Item
     * @param autoSelectHideItem    是否自动勾选
     */
    @Override
    public void setAutoSelectHideItem(boolean autoSelectHideItem) {
        getDelegate().setAutoSelectHideItem( autoSelectHideItem );
    }

    /**
     * 启用多选的状态
     * @return  是否已启用
     */
    @Override
    public boolean isEnableMultiSelect() { return getDelegate().isEnableMultiSelect(); }

    /**
     * 获取当前选中的数量
     * @return  数量
     */
    @Override
    public int getSelectedCount() { return getDelegate().getSelectedCount(); }

    /**
     * 是否为全选状态
     * @return  结果
     */
    @Override
    public boolean isSelectedAll() { return getDelegate().isSelectedAll(); }

    /**
     * 设置最大选中数量
     * @param count     数量。-1：没有限制
     */
    @Override
    public void setMaxMultiSelectCount(@IntRange(from = -1) int count) {
        getDelegate().setMaxMultiSelectCount( count );
    }

    /**
     * 获取最大选中数量
     * @return  数量
     */
    @Override
    public int getMaxMultiSelectCount() { return getDelegate().getMaxMultiSelectCount(); }

    /**
     * 设置最小选中数量
     * @param count             数量。0：没有限制
     * @param startPosition     起始位置。
     *                          当<code>isFirst</code>为false时，实际位置：size() - startPosition
     * @param isFirst           是否从上往下开始
     */
    @Override
    public void setMinMultiSelectCount(@IntRange(from = 0) int count,
                                       @IntRange(from = 0) int startPosition, boolean isFirst) {
        getDelegate().setMinMultiSelectCount( count, startPosition, isFirst );
    }

    /**
     * 设置最小选中数量
     * @param count             数量。0：没有限制
     * @param isFirst           是否从上往下开始
     */
    @Override
    public void setMinMultiSelectCount(@IntRange(from = 0) int count, boolean isFirst) {
        getDelegate().setMinMultiSelectCount( count, isFirst );
    }

    /**
     * 设置最小选中数量
     * @param count             数量。0：没有限制
     * @param startPosition     起始位置。
     *                          当<code>isFirst</code>为false时，实际位置：size() - startPosition
     */
    @Override
    public void setMinMultiSelectCount(@IntRange(from = 0) int count,
                                       @IntRange(from = 0) int startPosition) {
        getDelegate().setMinMultiSelectCount( count, startPosition );
    }

    /**
     * 设置最小选中数量
     * @param count             数量。0：没有限制
     */
    @Override
    public void setMinMultiSelectCount(@IntRange(from = 0) int count) {
        getDelegate().setMinMultiSelectCount( count );
    }

    /**
     * 获取最小选中数量
     * @return  数量
     */
    @Override
    public int getMinMultiSelectCount() { return getDelegate().getMinMultiSelectCount(); }

    /**
     * 多选下限的起始位置是否从顶部开始，否则从底部开始
     * @return  是否为顶部
     */
    @Override
    public boolean isFirstSelectOfMinCount() { return getDelegate().isFirstSelectOfMinCount(); }

    /**
     * 获取最小数量的起始位置
     * @return  位置
     */
    @Override
    public int getStartPositionOfMinCount() { return getDelegate().getStartPositionOfMinCount(); }

    /**
     * 设置替换上一个多选状态
     * 启用后，当到达{@link DelegateMultiSelect#getMaxMultiSelectCount()}上限时会取消上一个选中的状态
     * @param select    是否设置
     */
    @Override
    public void setReplaceLastSelect(boolean select) {
        getDelegate().setReplaceLastSelect( select );
    }

    /**
     * 是否替换上一个选中的状态
     * @return  结果
     */
    @Override
    public boolean isReplaceLastSelect() { return getDelegate().isReplaceLastSelect(); }

    /**
     * 选中/反选位置的多选状态
     * @param position  位置
     * @param enable    多选状态
     */
    @Override
    public void setMultiSelectStatus(int position, boolean enable) {
        getDelegate().setMultiSelectStatus( position, enable );
    }

    /**
     * 从上往下选中/反选多选状态
     * @param startPosition     起始位置
     * @param enable            多选状态
     */
    @Override
    public boolean setMultiSelectStatusOfFirst(int startPosition, boolean enable) {
        return getDelegate().setMultiSelectStatusOfFirst( startPosition, enable );
    }

    /**
     * 从上往下选中/反选多选状态
     * @param enable    多选状态
     */
    @Override
    public boolean setMultiSelectStatusOfFirst(boolean enable) {
        return getDelegate().setMultiSelectStatusOfFirst( enable );
    }

    /**
     * 从下往上选中/反选多选状态
     * @param endPosition       起始位置。实际位置：size() - endPosition
     * @param enable            多选状态
     */
    @Override
    public boolean setMultiSelectStatusOfLast(int endPosition, boolean enable) {
        return getDelegate().setMultiSelectStatusOfLast( endPosition, enable );
    }

    /**
     * 从下往上选中/反选多选状态
     * @param enable    多选状态
     */
    @Override
    public boolean setMultiSelectStatusOfLast(boolean enable) {
        return getDelegate().setMultiSelectStatusOfLast( enable );
    }

    /**
     * 选中/反选位置的多选状态
     * @param enable    多选状态
     */
    @Override
    public void setMultiSelectStatusAll(boolean enable) {
        getDelegate().setMultiSelectStatusAll( enable );
    }

    /**
     * 选中/反选位置的多选状态
     * @param position  位置
     */
    @Override
    public void switchMultiSelectStatus(int position) {
        getDelegate().switchMultiSelectStatus( position );
    }

    /**
     * 选中/反选所有多选状态
     */
    @Override
    public void switchMultiSelectStatusAll() { getDelegate().switchMultiSelectStatusAll(); }

    /**
     * 获取位置的多选状态
     * @param position  位置
     * @return          多选状态
     */
    @Override
    public boolean getMultiSelectStatus(int position) {
        return getDelegate().getMultiSelectStatus( position );
    }

    /**
     * 获取所有数据的多选状态
     * @return  列表
     */
    @Override
    public List<Boolean> getMultiSelectStatusAll() {
        return getDelegate().getMultiSelectStatusAll();
    }

    /**
     * 获取选中的数据列表
     * @return  数据源
     */
    @Override
    public List<E> getMultiSelectDataList() { return getDelegate().getMultiSelectDataList(); }

    /**
     * 是否存在选中
     * @return  结果
     */
    @Override
    public boolean isExistSelect() { return getDelegate().isExistSelect(); }

    /**
     * 指定位置增加一个多选状态
     * @param position  位置
     * @param enable    多选状态
     */
    @Override
    public void addMultiSelectStatus(int position, boolean enable) {
        getDelegate().addMultiSelectStatus( position, enable );
    }

    /**
     * 指定位置增加一个多选状态
     * @param position  位置
     */
    @Override
    public void addMultiSelectStatus(int position) {
        getDelegate().addMultiSelectStatus( position );
    }

    /**
     * 增加一个多选状态
     * @param enable    多选状态
     */
    @Override
    public boolean addMultiSelectStatus(boolean enable) {
        return getDelegate().addMultiSelectStatus( enable );
    }

    /**
     * 增加一个多选状态
     * @return  结果
     */
    @Override
    public boolean addMultiSelectStatus() { return getDelegate().addMultiSelectStatus(); }

    /**
     * 移除位置的多选状态
     * @param position  移除的位置
     */
    @Override
    public boolean removeMultiSelectStatus(int position) {
        return getDelegate().removeMultiSelectStatus( position );
    }

    /**
     * 移除位置的多选状态
     * @param data      移除的数据
     */
    @Override
    public boolean removeMultiSelectStatus(E data) {
        return getDelegate().removeMultiSelectStatus( data );
    }

    /**
     * 清空所有所有多选状态
     */
    @Override
    public void clearMultiSelectStatus() { getDelegate().clearMultiSelectStatus(); }

    /**
     * 增加一条数据
     * @param position  位置
     * @param enable    多选状态
     * @param data      数据源
     */
    @Override
    public boolean addItemData(int position, boolean enable, E data) {
        boolean ret = super.addItemData( position, data );
        getDelegate().addItemData( position, enable, data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param position  位置
     * @param enable    多选状态
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(int position, boolean enable, List<E> data) {
        boolean ret = super.addItemData( position, data );
        getDelegate().addItemData( position, enable, data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param enable    多选状态
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(boolean enable, E data) {
        boolean ret = super.addItemData( data );
        getDelegate().addItemData( enable, data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param enable    多选状态
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(boolean enable, List<E> data) {
        boolean ret = super.addItemData( data );
        getDelegate().addItemData( enable, data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(E data) {
        boolean ret = super.addItemData( data );
        getDelegate().addItemData( data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(List<E> data) {
        boolean ret = super.addItemData( data );
        getDelegate().addItemData( data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param position  添加的位置
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(int position, E data) {
        boolean ret = super.addItemData( position, data );
        getDelegate().addItemData( position, data );
        return ret;
    }

    /**
     * 增加一条数据
     * @param position  添加的位置
     * @param data      数据源
     * @return          结果
     */
    @Override
    public boolean addItemData(int position, List<E> data) {
        boolean ret = super.addItemData( position, data );
        getDelegate().addItemData( position, data );
        return ret;
    }

    /**
     * 设置一个位置的数据以及多选状态
     * @param position  位置
     * @param enable    多选状态
     * @param data      数据源
     * @return          之前的数据
     */
    @Override
    public E setItemData(int position, boolean enable, E data) {
        E ret = super.setItemData( position, data );
        getDelegate().setItemData( position, enable, data );
        return ret;
    }

    /**
     * 设置一个位置的数据以及多选状态
     * @param position  位置
     * @param data      数据源
     * @return          之前的数据
     */
    @Override
    public E setItemData(int position, E data) {
        E ret = super.setItemData( position, data );
        getDelegate().setItemData( position, data );
        return ret;
    }

    /**
     * 移除一个位置的数据源
     * @param position  位置
     * @return          结果
     */
    @Override
    public E removeItemData(int position) {
        E ret = super.removeItemData( position );
        getDelegate().removeItemData( position );
        return ret;
    }

    /**
     * 移除一个位置的数据源
     * @param data      数据
     * @return          结果
     */
    @Override
    public E removeItemData(E data) {
        E ret = super.removeItemData( data );
        getDelegate().removeItemData( data );
        return ret;
    }

    /**
     * 清空数据源
     */
    @Override
    public void clearItemData() {
        super.clearItemData();
        getDelegate().clearItemData();
    }
}